<template>
	<div id="info">
		<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - VRML loader
	</div>
</template>

<script src="./three.js-master/build/three.js"></script>
<script type="module">

export default {
  name: 'HelloWorld',
  data() {
    return {
      message: 'Hello, Vue!'
    };
  },
  methods: {
    greet() {
      alert(this.message);
    }
  }
};
import * as THREE from 'three';
import Stats from 'three/addons/libs/stats.module.js'; // 引入性能监测库，用于显示渲染性能
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // 引入轨道控制器，用于交互式控制相机
import { VRMLLoader } from 'three/addons/loaders/VRMLLoader.js'; // 引入VRML加载器，用于加载VRML格式的模型文件
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; // 引入GUI库，用于创建用户界面控件

// 定义全局变量
let camera, scene, renderer, stats, controls, loader;

const params = {
    asset: 'house' // 默认加载的模型名称
};

// 模型文件列表，可通过GUI切换加载不同的模型
const assets = [
    'creaseAngle',
    'crystal',
    'house',
    'elevationGrid1',
    'elevationGrid2',
    'extrusion1',
    'extrusion2',
    'extrusion3',
    'lines',
    'linesTransparent',
    'meshWithLines',
    'meshWithTexture',
    'pixelTexture',
    'points',
];

let vrmlScene; // 存储当前加载的VRML场景

// 初始化应用
init();

function init() {
    // 设置相机
    camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1e10); // 创建透视相机
    camera.position.set(-10, 5, 10); // 设置相机初始位置

    // 创建场景
    scene = new THREE.Scene();
    scene.add(camera); // 将相机添加到场景中

    // 添加光源
    const ambientLight = new THREE.AmbientLight(0xffffff, 1.2); // 环境光
    scene.add(ambientLight);

    const dirLight = new THREE.DirectionalLight(0xffffff, 2.0); // 平行光
    dirLight.position.set(200, 200, 200); // 设置光源位置
    scene.add(dirLight);

    // 初始化VRML加载器
    loader = new VRMLLoader();
    loadAsset(params.asset); // 加载默认模型

    // 初始化渲染器
    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio(window.devicePixelRatio); // 设置像素比
    renderer.setSize(window.innerWidth, window.innerHeight); // 设置渲染器大小
    renderer.setAnimationLoop(animate); // 启用渲染循环
    document.body.appendChild(renderer.domElement); // 将渲染器的DOM元素添加到页面

    // 初始化轨道控制器
    controls = new OrbitControls(camera, renderer.domElement);
    controls.minDistance = 1; // 设置最小缩放距离
    controls.maxDistance = 200; // 设置最大缩放距离
    controls.enableDamping = true; // 启用阻尼效果（平滑交互）

    // 初始化性能监测工具
    stats = new Stats();
    document.body.appendChild(stats.dom); // 将性能监测工具的DOM元素添加到页面

    // 添加窗口大小调整事件监听
    window.addEventListener('resize', onWindowResize);

    // 初始化GUI
    const gui = new GUI();
    gui.add(params, 'asset', assets).onChange(function (value) {
        if (vrmlScene) {
            // 卸载当前模型并释放资源
            vrmlScene.traverse(function (object) {
                if (object.material) object.material.dispose(); // 释放材质
                if (object.material && object.material.map) object.material.map.dispose(); // 释放纹理
                if (object.geometry) object.geometry.dispose(); // 释放几何体
            });
            scene.remove(vrmlScene); // 从场景中移除模型
        }
        loadAsset(value); // 加载新的模型
    });
}

// 加载指定的VRML模型
function loadAsset(asset) {
    loader.load('models/vrml/' + asset + '.wrl', function (object) {
        vrmlScene = object; // 存储加载的模型
        scene.add(object); // 将模型添加到场景
        controls.reset(); // 重置控制器
    });
}

// 处理窗口大小调整事件
function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight; // 更新相机宽高比
    camera.updateProjectionMatrix(); // 更新相机投影矩阵
    renderer.setSize(window.innerWidth, window.innerHeight); // 更新渲染器大小
}

// 渲染循环
function animate() {
    controls.update(); // 更新控制器（支持阻尼效果）
    renderer.render(scene, camera); // 渲染场景
    stats.update(); // 更新性能监测工具
}

</script>
<style>
body {
	margin: 0;
	background-color: #000;
	color: #fff;
	font-family: Monospace;
	font-size: 13px;
	line-height: 24px;
	overscroll-behavior: none;
}

a {
	color: #ff0;
	text-decoration: none;
}

a:hover {
	text-decoration: underline;
}

button {
	cursor: pointer;
	text-transform: uppercase;
}

#info {
	position: absolute;
	top: 0px;
	width: 100%;
	padding: 10px;
	box-sizing: border-box;
	text-align: center;
	-moz-user-select: none;
	-webkit-user-select: none;
	-ms-user-select: none;
	user-select: none;
	pointer-events: none;
	z-index: 1;
	/* TODO Solve this in HTML */
}

a,
button,
input,
select {
	pointer-events: auto;
}

.lil-gui {
	z-index: 2 !important;
	/* TODO Solve this in HTML */
}

@media all and (max-width: 640px) {
	.lil-gui.root {
		right: auto;
		top: auto;
		max-height: 50%;
		max-width: 80%;
		bottom: 0;
		left: 0;
	}
}

#overlay {
	position: absolute;
	font-size: 16px;
	z-index: 2;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-direction: column;
	background: rgba(0, 0, 0, 0.7);
}

#overlay button {
	background: transparent;
	border: 0;
	border: 1px solid rgb(255, 255, 255);
	border-radius: 4px;
	color: #ffffff;
	padding: 12px 18px;
	text-transform: uppercase;
	cursor: pointer;
}

#notSupported {
	width: 50%;
	margin: auto;
	background-color: #f00;
	margin-top: 20px;
	padding: 10px;
}
</style>